<template>
  <div class="box">
    <div v-for="n of all[0]" :key="n" class="item">
      <div class="item-child item-1">{{ n.val }}</div>
      <div class="item-child item-2" :class="{ 'ani-a': n.val != n.oldVal }">{{ n.val }}</div>
      <div class="item-child item-3" :class="{ 'ani-b': n.val != n.oldVal }">{{ n.oldVal }}</div>
      <div class="item-child item-4">{{ n.oldVal }}</div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'

const props = defineProps({
  num: [String, Number]
})

let dur = ref('1000ms')
let min = ref(5) // 最大位数

let oldNum = ref(0)
let newNum = ref(0)
let all = ref([])

watch(
  () => props.num,
  (v, o) => {
    oldNum.value = o ?? 0
    newNum.value = v
    let vS = newNum.value.toString()
    let oS = oldNum.value.toString()
    let lengthH = Math.max(Math.max(vS.length, oS.length), min.value)
    let val = vS.padStart(lengthH, '0').split('')
    let oVal = oS.padStart(lengthH, '0').split('')

    let vR = [...val].reverse()
    let oR = [...oVal].reverse()
    let lengthV = 0
    for (let i = 0; i < lengthH; i++) {
      lengthV = Math.max(Math.abs((vR[i] ?? 0) - (oR[i] ?? 0)), lengthV)
    }

    all.value = []
    for (let i = 0; i < lengthV; i++) {
      all.value[i] = []

      for (let j = 0; j < lengthH; j++) {
        let val, oldVal

        if (vR[j] > +oR[j] + i) {
          oldVal = +oR[j] + i
          val = +oR[j] + i + 1
        } else if (vR[j] < +oR[j] - i) {
          oldVal = +oR[j] - i
          val = +oR[j] - i - 1
        } else {
          val = oldVal = vR[j] ?? 0
        }

        all.value[i][j] = {
          val,
          oldVal
        }
      }
      all.value[i].reverse()
    }
  },
  {
    immediate: true
  }
)

let handle = () => {
  if (all.value.length > 1) {
    all.value.shift()

    setTimeout(() => handle(), Number.parseFloat(dur.value))
  }
}

watch(
  all,
  () => {
    handle()
  },
  {
    immediate: true
  }
)
</script>

<style scoped>
@font-face {
  font-family: num;
  src: url(./shuZi.ttf);
}

.box {
  display: flex;
}

.item {
  position: relative;
  transform-style: preserve-3d;
  perspective-origin: -300% 200%;
  perspective: 550px;
  width: 35px;
  height: 50px;
  margin: 0 2px;
  font-family: num;
  font-size: 40px;
}

.item-child {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  border-radius: 5px;
  box-shadow: rgba(255, 255, 255, 0.2) 0px 0px 5px 1px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.5);
  background-image: linear-gradient(
    #1d4299 0%,
    #1d4299 47%,
    #061e4f 47%,
    #061e4f 53%,
    #1d4299 53%,
    #1d4299 100%
  );
}

.item-1 {
  z-index: 1;
  clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
}

.item-2 {
  z-index: 3;
  bottom: 0;
  clip-path: polygon(0% 50%, 100% 50%, 100% 100%, 0% 100%);
  backface-visibility: hidden;
  transform: rotateX(180deg);
}

.item-3 {
  bottom: 0;
  z-index: 2;
  clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
  backface-visibility: hidden;
  transform: rotateX(0);
}

.item-4 {
  bottom: 0;
  z-index: 0;
}

.ani-a {
  animation: v-bind(dur) a forwards;
}

.ani-b {
  animation: v-bind(dur) b forwards;
}

@keyframes a {
  0% {
    transform: rotateX(180deg);
  }

  100% {
    transform: rotateX(0deg);
  }
}

@keyframes b {
  0% {
    transform: rotateX(0deg);
  }

  100% {
    transform: rotateX(-180deg);
  }
}
</style>
